using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;

namespace Common.Utilities
{
    /// <summary>
    /// 
    /// </summary>
    public class ContainerParserUtil
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="startPattern"></param>
        /// <param name="endPattern"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static Dictionary<int,string> ParseAllContainers(string startPattern, string endPattern, string content)
        {
            Dictionary<int, string> containerContents = new Dictionary<int, string>();
            Regex startRegex = new Regex(startPattern, RegexOptions.IgnoreCase);
            Regex endRegex = new Regex(endPattern, RegexOptions.IgnoreCase);
            List<int> startTagPositions = new List<int>();
            Match startMatch = startRegex.Match(content);
            while (startMatch.Success)
            {
                int pos = startMatch.Index;
                startTagPositions.Add(pos);
                startMatch = startMatch.NextMatch();
            }
            startTagPositions.Sort();
            Match endMatch = endRegex.Match(content);
            while (endMatch.Success)
            {
                int matchingStartTagPos = -1;
                if (startTagPositions.Count > 0)
                {
                    for (int i = 0; i < startTagPositions.Count; i++)
                    {
                        if (startTagPositions[i] < endMatch.Index)
                        {
                            matchingStartTagPos = startTagPositions[i];
                        }
                        else
                        {
                            if (matchingStartTagPos > 0 && i >= 1)
                            {
                                startTagPositions.RemoveAt(i - 1);
                            }
                            break;
                        }
                    }
                }
                if (matchingStartTagPos > 0)
                {
                    int pos = matchingStartTagPos;
                    int len = endMatch.Index + endMatch.Value.Length - pos;
                    string containerContent = content.Substring(pos, len);
                    containerContents.Add(pos, containerContent);
                }

                endMatch = endMatch.NextMatch();
            }

            return containerContents;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="startPattern"></param>
        /// <param name="endPattern"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static Dictionary<int, string> ParseRootContainers(string startPattern, string endPattern, string content)
        {
            Dictionary<int, string> allContainers =
                ContainerParserUtil.ParseAllContainers(startPattern, endPattern, content);
            Dictionary<int, string> rootContainsers = new Dictionary<int, string>();

            if(allContainers !=null && allContainers.Count>0)
            {
                List<Range<int>> boundaries = new List<Range<int>>();
                List<int> startPositionCollection = new List<int>();
                int[] startPositions = new int[allContainers.Count];
                allContainers.Keys.CopyTo(startPositions, 0);
                foreach (int startPos in startPositions)
                {
                    startPositionCollection.Add(startPos);
                }
                startPositionCollection.Sort();
                for(int i=0;i<startPositionCollection.Count;i++)
                {
                    int startPos = startPositionCollection[i];
                    int endPos = allContainers[startPos].Length + startPos;
                    Range<int> boundary = new Range<int>();
                    boundary.FromValue = startPos;
                    boundary.ToValue = endPos;
                    bool overLap = false;
                    if(boundaries.Count>0)
                    {
                        for(int k=0;k<boundaries.Count;k++)
                        {
                            if(boundary.OverlapWith(boundaries[k]))
                            {
                                overLap = true;
                                break;
                            }
                        }
                    }
                    if(!overLap)
                    {
                        boundaries.Add(boundary);
                    }
                }

                if(boundaries.Count>0)
                {
                    for(int i=0;i<boundaries.Count;i++)
                    {
                        rootContainsers.Add(boundaries[i].FromValue, allContainers[boundaries[i].FromValue]);
                    }
                }
            }

            

            return rootContainsers;
        }
    }
}
